// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently,
// but are changed infrequently

#pragma once

#include<algorithm>
#include<vector>
#include<utility>
#include<iostream>
#include<fstream>
#include<string>
#include<ctime>
#include<cstring>
#include<assert.h>
#include<windows.h>		//for reading PE files, obviously, not portable
#include<boost/regex.hpp>
#include"md5.h"


#define DEFAULT_LOGFILE "kkLog.log"

namespace KillerKitty {

	//enums
	//IMPORTANT : always place the constant indicating the nonexistence of something, at the end of the enum list
	// eg. noVir, noField, noSig, none, noPrefix
	//IMPORTANT : if u make any changes to the following enums, then also modify the corresponding strings in kkSignatureParser also
	
	enum logLevel_e {debug, info, warn, error, none };	
	enum virType_e { virAny, virPE, virOLE2, virHTML, virMail, virGraphics,virELF,noVir }; 
	
	//Unfortunately, Virus Names in Clam have spelling mistakes some times :( 
	//Flodder and Virtool have been included to parse virus names with spelling mistakes too :)
	//I couldnot find a better solution for parsing those spelling mistakes :(
   
	enum virNamePrefix_e { ASP, Adware, BAT, DOS, Dialer, DoS, Email, Exploit, 
						   Flodder, Flooder, HTML, IRC, JS, Joke, O2000M, O97M, 
						   PHP, Trojan, VBS, VirTool, Virtool, W2000M, W97M, Worm, 
						   X2000M, X97M, noPrefix };

	const int PREFIXCNT=26; //enum constant noPrefix is not included in  prefixCnt

	enum sigType_e { sigStatic, sigDynamic, sigOther,noSig };	//static->uses MD5 hash, dynamic->hex signature, other->not used right now
	enum srcFile_e { daily_hdb,main_hdb,daily_ndb,main_ndb,daily_db,main_db,noFile }; //_xyz stands for the extendsion
	enum recDelimiter_e { colon,equalto };
	enum recFields_e {name,hexcode,offset,fileLength,srcFile,sigType,virType,virNamePrefix, noField};
	
	struct kkSignature_t {
		char *name;	//name of the virus
		char *hexcode;	//the signature for the virus. For static, it is the correspoding md5 checksum and for dynamic it is the corresponding hexsignature
		char *offset;	//string, refers to the offset at which to search for the signature. (can be n, EOF-n,*,EP+n etc where n -> integer)
		
		unsigned long fileLength;

		srcFile_e srcFile;
		sigType_e sigType;	//the signature type, whether static or dynamic
		virType_e virType;	//virus type
		virNamePrefix_e virNamePrefix;
		//returns true if a regular expression is present in the given string
		static bool isRegExPresent(char *str) {
			int count=0;

			while((*str)!='\0') {
				//'|' could also be searched but it is never used without (, so redundant, and ( will appear first anyway, so a bit more faster :)
				if(isCharRegEx(*str)) return true;
				str++;
			}

			return false;
		}

		static inline bool isCharRegEx(char ch) {
			if(ch=='?' || ch=='*' || ch=='{' || ch=='(' || ch=='|') return true;
			else return false;
		}

		public:
			kkSignature_t(void) {
				name=NULL;
				hexcode=NULL;
				offset=NULL;
				srcFile=noFile;
				sigType=noSig;
				virType=noVir;
				virNamePrefix=noPrefix;
				fileLength=0;
			}

			kkSignature_t(sigType_e sigType,srcFile_e srcFile) {

				this->name=NULL;
				this->hexcode=NULL;
				this->offset=NULL;
				
				this->sigType=sigType;
				this->srcFile=srcFile;
				this->virNamePrefix=noPrefix;
				
				if(this->sigType==sigStatic) {
				    /*
					 In case of static virus database files, set offset and virus type before tokenising the line read from the data base.
					 This is done because, offset and virus type(target type) are not specified in these .hdb data bases
				    */
					this->virType=virAny;			
					this->offset="NONE";
				}
				else if (this->sigType==sigDynamic) {
					this->fileLength=0;
					/*
					 In case of .db files, set offset and virus type before tokenising the line read from the data base.
					 This is done because, offset and virus type(target type) are not specified in these .db data bases
					*/
					if(srcFile==daily_db || srcFile==main_db){
						this->virType=virAny;
						this->offset="*";
					}

				}
						
			}
			

			~kkSignature_t() {
				delete name;
				delete hexcode;
				//Because, offsets are compile time string constants for other file types, and so they cant b deleted
				if(srcFile==daily_ndb || srcFile==main_ndb)
					delete offset;
			}

			
	};

	//Used to store the indices of dbHolder, after sorting it according to the virus name prefixes.


	struct prefixInfo{
		unsigned long start;
		unsigned long end;
		virNamePrefix_e prefix;

		prefixInfo(long start,long end,virNamePrefix_e prefix){			

			this->start=start;
			this->end=end;
			this->prefix=prefix;
		}



	};



	//neccessary for RTTI to work in kkLogger
	class KillerKittyBase {
	public:
		KillerKittyBase(){};
		virtual ~KillerKittyBase()=0{};

	};

}
